package com.raymond.cmpp.client.handler;

import com.alibaba.fastjson.JSONObject;
import com.raymond.cmpp.client.CmppClient;
import com.raymond.cmpp.client.msg.MessageManages;
import com.raymond.cmpp.common.msg.BaseMessage;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.ConcurrentHashMap;

/**
 * 业务处理基础类
 *
 * @author :  raymond
 * @version :  V1.0
 * @date :  2021-08-06 11:39
 */
public abstract class BaseBusinessHandler<I extends BaseMessage> extends SimpleChannelInboundHandler<BaseMessage> {
    private final static Logger logger = LoggerFactory.getLogger(BaseBusinessHandler.class);
    /**
     * 客户端连接信息
     */
    CmppClient cmppClient;
    /**
     * 消息管理器
     */
    final ConcurrentHashMap<Integer, MessageManages> msgManager;

    BaseBusinessHandler(Class<? extends BaseMessage> inboundMessageType, CmppClient cmppClient) {
        super(inboundMessageType);
        this.cmppClient = cmppClient;
        this.msgManager = cmppClient.getMsgManager();
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, BaseMessage msg) throws Exception {
        @SuppressWarnings("unchecked")
        I iMsg = (I) msg;
        channelRead(ctx, iMsg);
    }

    /**
     * 当前消息找不到对应的请求
     * @param resp resp
     */
    private void notRequest(BaseMessage resp) {
        logger.warn("当前消息找不到对应的请求:{}", resp);
    }

    /**
     * 找到对应的请求通知
     * @param resp 响应
     */
    void responseNotice(BaseMessage resp) {
        MessageManages remove = msgManager.remove(resp.getSequenceId());
        logger.debug("收到一条响应,响应:{},请求:{}", JSONObject.toJSONString(resp), JSONObject.toJSONString(remove));
        if (remove != null) {
            remove.success(resp);
        } else {
            notRequest(resp);
        }
    }

    /**
     * 读取数据处理
     * @param ctx ctx
     * @param msg 消息对象
     * @throws Exception 异常
     */
    protected abstract void channelRead(ChannelHandlerContext ctx, I msg) throws Exception;

}
